package com.thunbu.lib_common.utils

import android.Manifest
import android.R
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.telephony.TelephonyManager
import android.text.TextUtils
import android.view.View
import com.thunbu.lib_common.base.BaseApplication

import java.io.*
import java.net.NetworkInterface
import java.util.*

/**
 * Created by spcace.cong@gmail.com on 2017/11/27.
 */
object DeviceUtil {
    private const val TAG = "DeviceUtil"
    private const val BRAND_HUAWEI = "HUAWEI"
    private const val BRAND_NONE = "none"

    // 检测 MIUI
    private const val KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code"
    private const val KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name"
    private const val KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage"
    var isMIUI = false
        private set
    val isHWPhone: Boolean
        get() = BRAND_HUAWEI.equals(mobileBrand, ignoreCase = true)

    fun checkMobile(mobile: String): Boolean {
        val telRegex = "^\\d{11}$"
        return mobile.matches(Regex(telRegex))
    }

    /**
     * 判断是否为小米系统手机
     *
     * @return
     */
    fun justIsMIUI() {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
            if (!TextUtils.isEmpty(getSystemProperty(KEY_MIUI_VERSION_CODE, ""))
                    || !TextUtils.isEmpty(getSystemProperty(KEY_MIUI_VERSION_NAME, ""))
                    || !TextUtils.isEmpty(getSystemProperty(KEY_MIUI_INTERNAL_STORAGE, ""))) {
                isMIUI = true
            }
        } else {
            val prop = Properties()
            var fis: FileInputStream? = null
            try {
                fis = FileInputStream(File(Environment.getRootDirectory(), "build.prop"))
                prop.load(fis)
            } catch (e: IOException) {

            } finally {
                if (fis != null) {
                    try {
                        fis.close()
                    } catch (e: IOException) {

                    }
                }
            }
            isMIUI = prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null || prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null
        }
    }

    // Invoke Build.hasSmartBar()
    val isFlyme: Boolean
        get() = try {
            // Invoke Build.hasSmartBar()
            val method = Build::class.java.getMethod("hasSmartBar")
            method != null
        } catch (e: Exception) {
            false
        }

    /**
     * 获取手机品牌
     */
    val mobileBrand: String
        get() {
            val manufacturer = Build.MANUFACTURER
            return if (!TextUtils.isEmpty(manufacturer)) {
                manufacturer.toLowerCase()
            } else {
                BRAND_NONE
            }
        }

    private fun checkRootMethod1(): Boolean {
        val buildTags = Build.TAGS
        return buildTags != null && buildTags.contains("test-keys")
    }

    private fun checkRootMethod2(): Boolean {
        val paths = arrayOf("/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su",
                "/system/bin/failsafe/su", "/data/local/su", "/su/bin/su")
        for (path in paths) {
            if (File(path).exists()) return true
        }
        return false
    }

    private fun checkRootMethod3(): Boolean {
        var process: Process? = null
        return try {
            process = Runtime.getRuntime().exec(arrayOf("/system/xbin/which", "su"))
            val bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
            bufferedReader.readLine() != null
        } catch (t: Throwable) {
            false
        } finally {
            process?.destroy()
        }
    }

    fun getAppVersionName(context: Context): String {
        var versionName = ""
        try {
            versionName = context.packageManager
                    .getPackageInfo(context.packageName, 0).versionName
        } catch (e: PackageManager.NameNotFoundException) {

        }
        return versionName
    }

    // 手机品牌
    // 手机型号
    val phoneBrand: String
        get() {
            val mtype = Build.MODEL // 手机型号
            val mtyb = Build.BRAND // 手机品牌
            return "$mtyb $mtype"
        }

    /**
     * 获取当前手机系统(android)版本号
     *
     * @return  系统版本号
     */
    val phoneVersion: String
        get() = Build.VERSION.RELEASE

    val appVersionName: String
        get() {
            var versionName = ""
            val context: Context = BaseApplication.getInstance()
            try {
                versionName = context.packageManager
                        .getPackageInfo(context.packageName, 0).versionName
            } catch (e: PackageManager.NameNotFoundException) {

            }
            return versionName
        }

    val versionCode: Int
        get() {
            val context: Context = BaseApplication.getInstance()
            var appVersion = -1
            try {
                appVersion = context.packageManager.getPackageInfo(
                        context.packageName,
                        PackageManager.GET_META_DATA).versionCode
            } catch (e: PackageManager.NameNotFoundException) {

            }
            return appVersion
        }

    /**
     * 适配Android 7.1
     *
     * @param key
     * @param defaultValue
     * @return
     */
    private fun getSystemProperty(key: String, defaultValue: String): String {
        try {
            val clz = Class.forName("android.os.SystemProperties")
            val get = clz.getMethod("get", String::class.java, String::class.java)
            return get.invoke(clz, key, defaultValue) as String
        } catch (e: Exception) {
        }
        return defaultValue
    }

    /**
     * 虚拟按键高度
     *
     * @param context
     * @return
     */
    fun getNavigationBarHeight(context: Activity): Int {
        return if (isNavigationBarShown(context)) {
            var result = 0
            val resourceId = context.resources.getIdentifier("navigation_bar_height", "dimen", "android")
            if (resourceId > 0) {
                result = context.resources.getDimensionPixelSize(resourceId)
            }
            result
        } else {
            0
        }
    }


    /**
     * 虚拟按键是否打开
     *
     * @param activity
     * @return
     */
    fun isNavigationBarShown(activity: Activity): Boolean {
        //虚拟键的view,为空或者不可见时是隐藏状态
        val view = activity.findViewById<View>(R.id.navigationBarBackground) ?: return false
        val visible = view.visibility
        return visible == View.VISIBLE
    }


    /**
     * 获取MAC地址
     *
     * @return
     */
    fun getMacAddress(context: Context?): String? {
        return when {
            Build.VERSION.SDK_INT < Build.VERSION_CODES.M -> {
                getMacDefault(context)
            }
            Build.VERSION.SDK_INT < Build.VERSION_CODES.N -> {
                macFromFile
            }
            else -> {
                macFromHardware
            }
        }
    }

    /**
     * Android  6.0 之前（不包括6.0）
     * 必须的权限  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
     *
     * @param context
     * @return
     */
    private fun getMacDefault(context: Context?): String? {
        var mac = "02:00:00:00:00:00"
        if (context == null) {
            return mac
        }
        val wifi = context.applicationContext
                .getSystemService(Context.WIFI_SERVICE) as WifiManager ?: return mac
        var info: WifiInfo? = null
        try {
            info = wifi.connectionInfo
        } catch (e: Exception) {
        }
        if (info == null) {
            return null
        }
        mac = info.macAddress
        if (!TextUtils.isEmpty(mac)) {
            mac = mac.toUpperCase(Locale.ENGLISH)
        }
        return mac
    }

    /**
     * Android 6.0（包括） - Android 7.0（不包括）
     *
     * @return
     */
    private val macFromFile: String
        private get() {
            var WifiAddress = "02:00:00:00:00:00"
            try {
                WifiAddress = BufferedReader(FileReader(File("/sys/class/net/wlan0/address"))).readLine()
            } catch (e: IOException) {
                e.printStackTrace()
            }
            return WifiAddress
        }

    /**
     * 遍历循环所有的网络接口，找到接口是 wlan0
     * 必须的权限 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
     *
     * @return
     */
    private val macFromHardware: String
        private get() {
            try {
                val all: List<NetworkInterface> = Collections.list(NetworkInterface.getNetworkInterfaces())
                for (nif in all) {
                    if (!nif.name.equals("wlan0", ignoreCase = true)) {
                        continue
                    }
                    val macBytes = nif.hardwareAddress ?: return ""
                    val res1 = StringBuilder()
                    for (b in macBytes) {
                        res1.append(String.format("%02X:", b))
                    }
                    if (res1.isNotEmpty()) {
                        res1.deleteCharAt(res1.length - 1)
                    }
                    return res1.toString()
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return "02:00:00:00:00:00"
        }

    fun getDeviceId(): String {
        val context: Context = BaseApplication.getInstance()
        var deviceId = Settings.System.getString(
                context.contentResolver, Settings.Secure.ANDROID_ID)
        if(deviceId.isNullOrEmpty()){
            deviceId = uniqueString()
        }
        return deviceId
    }

    private fun uniqueString(): String {
        return "35" + Build.BOARD.length % 10 + Build.BRAND.length % 10 + Build.CPU_ABI.length % 10 + Build.DEVICE.length % 10 + Build.DISPLAY.length % 10 + Build.HOST.length % 10 + Build.ID.length % 10 + Build.MANUFACTURER.length % 10 + Build.MODEL.length % 10 + Build.PRODUCT.length % 10 + Build.TAGS.length % 10 + Build.TYPE.length % 10 + Build.USER.length % 10
    }
}